TOOL.Category = '(Shanjaq)'
TOOL.Name = '#Generators'
TOOL.Command = nil
TOOL.ConfigName = ''

TOOL.ClientConVar['type'] = 'air_compressor'

TOOL.ClientConVar['model'] = 'models/props_wasteland/laundry_washer003.mdl'

cleanup.Register('energysystem')
cleanup.Register( 'tankconstraints' )


if ( CLIENT ) then
	language.Add( 'Tool_energysystems_name', 'Energy Systems (Shanjaq)' )
	language.Add( 'Tool_energysystems_desc', 'Create Generators attached to any surface.' )
	language.Add( 'Tool_energysystems_0', 'Left-Click: Spawn a Device.  Right-Click: Repair Device.' )

	language.Add( 'Undone_EnergySystem', 'Energy Systems Device Undone' )
	language.Add( 'Undone_Hose', 'Energy Conduit Undone' )
	language.Add( 'Cleanup_airtanks', 'Energy System' )
	language.Add( 'Cleaned_airtank', 'Cleaned up all Life Support Devices' )
	language.Add( 'SBoxLimit_energysystems', 'Maximum Life Support Devices Reached' )
end


if ( GAMEMODE.Name == "SpaceBuild" || SpaceBuild ) then 
	energysystem_models = {
		{ 'Air Compressor', 'models/props_wasteland/laundry_washer003.mdl', 'air_compressor' },
		{ 'Oxygen Scrubber', 'models/props_c17/light_decklight01_off.mdl', 'air_scrubber' },
		{ 'H2O Destabilizer', 'models/props_c17/FurnitureBoiler001a.mdl', 'water_destabilizer' },
		{ 'Hydrogen Processor', 'models/props/de_nuke/coolingtank.mdl', 'hydrogen_processor' },
		{ 'Hydrogen Scoop', 'models/props/CS_militia/lightfixture01.mdl', 'ramscoop_drive' },
		{ 'Coolant Compressor', 'models/Gibs/airboat_broken_engine.mdl', 'coolant_compressor' },
		{ 'Coolant Electrolyzer', 'models/props_c17/TrapPropeller_Engine.mdl', 'coolant_electrolyzer' },
		{ 'Coolant Delectrolyzer', 'models/props_c17/TrapPropeller_Engine.mdl', 'coolant_delectrolyzer' },
		{ 'Solar Panel', 'models/props_trainstation/traincar_rack001.mdl', 'energy_solar' },
		{ 'Wind Generator', 'models/props_trainstation/pole_448Connection001a.mdl', 'energy_wind' },
		{ 'Hydro Generator', 'models/props_wasteland/coolingtank01.mdl', 'energy_hydro' },
		{ 'Fusion Generator', 'models//props_c17/substation_circuitbreaker01a.mdl', 'warp_core' },
		{ 'Microfusion Reactor', 'models//props_combine/headcrabcannister01a.mdl', 'microfusion_core' },
		{ 'Nuclear Decay Generator', 'models/jaanus/nuke.mdl', 'nuc_decay_gen' },
		{ 'Universal Resource Generator', 'models/props/cs_assault/ACUnit01.mdl', 'uni_res_gen' },
		{ 'Fission Core', 'models/props_lab/generator.mdl', 'fission_core' },
		{ 'Uranium Miner', 'models/props_trainstation/trashcan_indoor001b.mdl', 'uranium_miner' }
	}
else
	energysystem_models = {
		{ 'Air Compressor', 'models/props_wasteland/laundry_washer003.mdl', 'air_compressor' },
		{ 'Oxygen Scrubber', 'models/props_c17/light_decklight01_off.mdl', 'air_scrubber' },
		{ 'H2O Destabilizer', 'models/props_c17/FurnitureBoiler001a.mdl', 'water_destabilizer' },
		{ 'Hydrogen Processor', 'models/props/de_nuke/coolingtank.mdl', 'hydrogen_processor' },
		{ 'Hydrogen Scoop', 'models/props/CS_militia/lightfixture01.mdl', 'ramscoop_drive' },
		{ 'Coolant Compressor', 'models/Gibs/airboat_broken_engine.mdl', 'coolant_compressor' },
		{ 'Coolant Electrolyzer', 'models/props_c17/TrapPropeller_Engine.mdl', 'coolant_electrolyzer' },
		{ 'Coolant Delectrolyzer', 'models/props_c17/TrapPropeller_Engine.mdl', 'coolant_delectrolyzer' },
		{ 'Solar Panel', 'models/props_trainstation/traincar_rack001.mdl', 'energy_solar' },
		{ 'Wind Generator', 'models/props_trainstation/pole_448Connection001a.mdl', 'energy_wind' },
		{ 'Hydro Generator', 'models/props_wasteland/coolingtank01.mdl', 'energy_hydro' },
		{ 'Fusion Generator', 'models//props_c17/substation_circuitbreaker01a.mdl', 'warp_core' },
		{ 'Microfusion Reactor', 'models//props_combine/headcrabcannister01a.mdl', 'microfusion_core' },
		{ 'Nuclear Decay Generator', 'models/jaanus/nuke.mdl', 'nuc_decay_gen' },
		{ 'Universal Resource Generator', 'models/props/cs_assault/ACUnit01.mdl', 'uni_res_gen' },
		{ 'Fission Core', 'models/props_lab/generator.mdl', 'fission_core' },
		{ 'Uranium Miner', 'models/props_trainstation/trashcan_indoor001b.mdl', 'uranium_miner' }
	}
end

--models//props_combine/combine_tptimer.mdl
--models//props_c17/substation_circuitbreaker01a.mdl
--models/props_c17/factorymachine01.mdl

--for wind top
--models/props_citizen_tech/windmill_blade004a.mdl
--smaller  solar?
--models/props_lab/lockerdoorleft.mdl
--models//props_vehicles/generatortrailer01.mdl
function TOOL:LeftClick( trace )
	if trace.Entity && (trace.Entity:IsPlayer() ) then return false end
	
	if(CLIENT) then
		return true
	end

	if(!SERVER) then return false end

	if ( !self:GetSWEP():CheckLimit( "energysystems" ) ) then return false end

	local ply = self:GetOwner()
	local Pos = trace.HitPos
	local Ang = trace.HitNormal:Angle()
	Ang.pitch = Ang.pitch + 90
	
	local energy_system_type		= self:GetClientInfo('type')
	local energy_system_model	= self:GetClientInfo('model')
	ent = MakeEnergySystem( ply, Ang, Pos, energy_system_type, energy_system_model )
	ent:SetPos( trace.HitPos - trace.HitNormal * ent:OBBMins().z)
	
	if ( trace.Entity:IsValid() ) then
		local const = constraint.Weld(ent, trace.Entity,0, trace.PhysicsBone, 0, systemmanager )
		nocollide = constraint.NoCollide( ent, trace.Entity, 0, trace.PhysicsBone )
		trace.Entity:DeleteOnRemove( ent )
	end

	undo.Create('EnergySystem')
		undo.AddEntity( ent)
		undo.AddEntity( const )
		undo.AddEntity( nocollide )
		undo.SetPlayer( ply )
	undo.Finish()


	ply:AddCleanup( 'energysystem', const )
	ply:AddCleanup( 'energysystem', nocollide )
	
	return true
end



function TOOL:RightClick( trace )
	if (not trace.Entity:GetTable().Repair) then
        self:GetOwner():SendLua( "GAMEMODE:AddNotify('Object cannot be repaired!', NOTIFY_GENERIC, 7);" )
		return
	end
	trace.Entity:Repair()
	return true
end


function TOOL:Reload(trace)
	return true
end




if SERVER then 
    CreateConVar('sbox_maxenergysystems',24)
	
	function MakeEnergySystem( ply, Ang, Pos, energy_system_type, model )
		if ( !ply:CheckLimit( "energysystems" ) ) then return nil end
		if not ( RES_DISTRIB == 1 ) then
			ply:PrintMessage( HUD_PRINTCENTER, "Please Install Resource Distribution Addon.\nThis mod requires it to function.\nSearch GarrysMod.org for 'distribution'" )  
			return
		end

		local ent = ents.Create( energy_system_type )
			if !ent:IsValid() then return false end
			ent:SetModel( model )
			ent:SetAngles(Ang)
			ent:SetPos(Pos)
		ent:Spawn()

		ent:SetVar('Owner',ply)
		
		local phys = ent:GetPhysicsObject()
		local resp = 0
		local Active = 0
		local range = 0
		local max_health = 0
		local NextThink = CurTime() +  1
		
		if (energy_system_type == "air_compressor") then
			max_health = 600
			RD_AddResource(ent, "air", 0)
			RD_AddResource(ent, "energy", 0)
		
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				habitat = 1,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'air_compressor', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "air_scrubber") then
			max_health = 100
			RD_AddResource(ent, "air", 0)
			RD_AddResource(ent, "energy", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'air_scrubber', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "water_destabilizer") then
			max_health = 100
			RD_AddResource(ent, "hydrogen", 0)
			RD_AddResource(ent, "air", 0)
			RD_AddResource(ent, "energy", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'water_destabilizer', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "hydrogen_processor") then
			max_health = 1500
			RD_AddResource(ent, "hydrogen", 15000)
			RD_AddResource(ent, "energy", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'hydrogen_processor', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "ramscoop_drive") then
			max_health = 1000
			
			RD_AddResource(ent, "hydrogen", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}

			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'ramscoop_drive', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "coolant_compressor") then
			max_health = 400
			RD_AddResource(ent, "energy", 0)
			RD_AddResource(ent, "coolant", 0)

			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'coolant_compressor', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "energy_solar") then
			max_health = 300
			RD_AddResource(ent, "energy", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'energy_solar', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "energy_wind") then
			max_health = 400
			RD_AddResource(ent, "energy", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'energy_wind', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "energy_hydro") then
			max_health = 600
			RD_AddResource(ent, "energy", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'energy_hydro', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "warp_core") then
			max_health = 1000
			RD_AddResource(ent, "energy", 0)
			RD_AddResource(ent, "coolant", 0)
			RD_AddResource(ent, "hydrogen", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'warp_core', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "microfusion_core") then
			max_health = 250
			RD_AddResource(ent, "energy", 0)
			RD_AddResource(ent, "coolant", 0)
			RD_AddResource(ent, "hydrogen", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
				
				
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'microfusion_core', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "coolant_electrolyzer") then
			max_health = 500
			RD_AddResource(ent, "energy", 0)
			RD_AddResource(ent, "coolant", 0)
			RD_AddResource(ent, "air", 0)
			RD_AddResource(ent, "hydrogen", 0)

			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'coolant_electrolyzer', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "coolant_delectrolyzer") then
			max_health = 500
			RD_AddResource(ent, "energy", 0)
			RD_AddResource(ent, "coolant", 0)
			RD_AddResource(ent, "air", 0)
			RD_AddResource(ent, "hydrogen", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'coolant_delectrolyzer', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "nuc_decay_gen") then
			max_health = 100
			RD_AddResource(ent, "energy", 50)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'nuc_decay_gen', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "uni_res_gen") then
			max_health = 500
			RD_AddResource(ent, "energy", 0)
			RD_AddResource(ent, "coolant", 0)
			RD_AddResource(ent, "air", 0)
			RD_AddResource(ent, "hydrogen", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
			table.Merge(ent:GetTable(), rtable )
--			duplicator.RegisterEntityClass( 'uni_res_gen', MakeEnergySystem,  'Ang', 'Pos', 'energy_system_type', 'model' )
		elseif (energy_system_type == "fission_core") then
			max_health = 5000
			RD_AddResource(ent, "energy", 0)
			RD_AddResource(ent, "coolant", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
			table.Merge(ent:GetTable(), rtable )
		elseif (energy_system_type == "uranium_miner") then
			max_health = 3500
			RD_AddResource(ent, "energy", 0)
			
			local rtable = {
				energy_system_type = energy_system_type,
				model = model,
				atmosphere = 1,
				Active = Active,
				running = 0,
				max_health = max_health,
				health = max_health,
				NextThink = NextThink
				}
			table.Merge(ent:GetTable(), rtable )
		end
		if ent:GetTable().OnTakeDamage then
			local Prev = ent:GetTable().OnTakeDamage
			
			function ent:OnTakeDamage(Info)
				DamageLS(self, Info:GetDamage())
				Prev(self, Info)
			end
		end
		
		ply:AddCount('energysystems', ent)
		
		return ent    
	end	 
	duplicator.RegisterEntityClass("air_compressor", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("air_scrubber", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("coolant_compressor", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("energy_solar", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("energy_wind", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("energy_hydro", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("warp_core", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("hydrogen_processor", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("water_destabilizer", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("microfusion_core", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("ramscoop_drive", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("coolant_electrolyzer", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("coolant_delectrolyzer", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("uni_res_gen", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("nuc_decay_gen", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("fission_core", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
	duplicator.RegisterEntityClass("uranium_miner", MakeEnergySystem, "Ang", "Pos", "energy_system_type", "model", "Vel", "aVel", "frozen")
end

function TOOL.BuildCPanel( cp )
	cp:AddControl( 'Header', { Text = '#Tool_energysystems_name', Description	= '#Tool_energysystems_desc' }  )

	local combo = {}
	combo.Label = 'Life Support Device'
	combo.MenuButton = 1
	combo.Folder = 'settings/menu/main/construct/energysystems/'
	combo.Options = {}
	
	for k, v in pairs(energysystem_models) do
	  combo.Options[v[1]] = { energysystems_model = v[2], energysystems_type = v[3] }
	end

	cp:AddControl('ComboBox', combo) 

end

function TOOL:UpdateGhostEnergySystem( ent, player )

	if ( !ent ) then return end
	if ( !ent:IsValid() ) then return end
	local tr 	= utilx.GetPlayerTrace( player, player:GetCursorAimVector() )
	local trace 	= util.TraceLine( tr )
	if (!trace.Hit) then return end
	
	if ( trace.Entity:IsPlayer() ) then
	
		ent:SetNoDraw( true )
		return
		
	end
	
	local Ang = trace.HitNormal:Angle()
	Ang.pitch = Ang.pitch + 90
	ent:SetAngles( Ang )
	
	local min = ent:OBBMins()
	ent:SetPos( trace.HitPos - trace.HitNormal * min.z )
	
	ent:SetNoDraw( false )
	
end


function TOOL:Think()
	local model	= self:GetClientInfo('model')
	
	if (!self.GhostEntity || !self.GhostEntity:IsValid() || self.GhostEntity:GetModel() != model) then
		self:MakeGhostEntity( model, Vector(0,0,0), Angle(0,0,0) )
	end
	
	self:UpdateGhostEnergySystem( self.GhostEntity, self:GetOwner() )
end